[message].page.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import React from 'react';
  2. import type {
  3. GetServerSideProps,
  4. GetServerSidePropsContext,
  5. NextPage,
  6. } from 'next';
  7. import { useTranslation } from 'next-i18next';
  8. import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
  9. import { useRouter } from 'next/router';
  10. import { NoLoginLayout } from '~/components/Layout/NoLoginLayout';
  11. import type { CommonProps } from '~/pages/utils/commons';
  12. import {
  13. getNextI18NextConfig,
  14. getServerSideCommonProps,
  15. } from '~/pages/utils/commons';
  16. type Props = CommonProps;
  17. const classNames: string[] = ['login-page'];
  18. const LoginPage: NextPage<CommonProps> = () => {
  19. const { t } = useTranslation();
  20. const router = useRouter();
  21. const { message } = router.query;
  22. let loginErrorElm;
  23. const ApprovalPendingUserError = () => {
  24. return (
  25. <>
  26. <div className="alert alert-warning">
  27. <h2>{t('login.sign_in_error')}</h2>
  28. </div>
  29. <p>Wait for approved by administrators.</p>
  30. </>
  31. );
  32. };
  33. const SuspendedUserError = () => {
  34. return (
  35. <>
  36. <div className="alert alert-warning">
  37. <h2>{t('login.sign_in_error')}</h2>
  38. </div>
  39. <p>This account is suspended.</p>
  40. </>
  41. );
  42. };
  43. const PasswordResetOrderError = () => {
  44. return (
  45. <>
  46. <div className="alert alert-warning mb-3">
  47. <h2>{t('forgot_password.incorrect_token_or_expired_url')}</h2>
  48. </div>
  49. <a href="/forgot-password" className="link-switch">
  50. <span className="material-symbols-outlined">key</span>{' '}
  51. {t('forgot_password.forgot_password')}
  52. </a>
  53. </>
  54. );
  55. };
  56. const DefaultLoginError = () => {
  57. return (
  58. <div className="alert alert-warning">
  59. <h2>{t('login.sign_in_error')}</h2>
  60. </div>
  61. );
  62. };
  63. switch (message) {
  64. case 'registered':
  65. loginErrorElm = <ApprovalPendingUserError />;
  66. break;
  67. case 'suspended':
  68. loginErrorElm = <SuspendedUserError />;
  69. break;
  70. case 'password-reset-order':
  71. loginErrorElm = <PasswordResetOrderError />;
  72. break;
  73. default:
  74. loginErrorElm = <DefaultLoginError />;
  75. }
  76. return (
  77. <NoLoginLayout className={classNames.join(' ')}>
  78. <div className="mb-4 login-form-errors text-center">
  79. <div className="nologin-dialog pb-4 mx-auto">
  80. <div className="col-12">{loginErrorElm}</div>
  81. {/* If the transition source is "/login", use <a /> tag since the transition will not occur if next/link is used. */}
  82. <a href="/login">
  83. <span className="material-symbols-outlined me-1">login</span>
  84. {t('Sign in is here')}
  85. </a>
  86. </div>
  87. </div>
  88. </NoLoginLayout>
  89. );
  90. };
  91. /**
  92. * for Server Side Translations
  93. * @param context
  94. * @param props
  95. * @param namespacesRequired
  96. */
  97. async function injectNextI18NextConfigurations(
  98. context: GetServerSidePropsContext,
  99. props: Props,
  100. namespacesRequired?: string[] | undefined,
  101. ): Promise<void> {
  102. const nextI18NextConfig = await getNextI18NextConfig(
  103. serverSideTranslations,
  104. context,
  105. namespacesRequired,
  106. );
  107. props._nextI18Next = nextI18NextConfig._nextI18Next;
  108. }
  109. export const getServerSideProps: GetServerSideProps = async(
  110. context: GetServerSidePropsContext,
  111. ) => {
  112. const result = await getServerSideCommonProps(context);
  113. // check for presence
  114. // see: https://github.com/vercel/next.js/issues/19271#issuecomment-730006862
  115. if (!('props' in result)) {
  116. throw new Error('invalid getSSP result');
  117. }
  118. const props: Props = result.props as Props;
  119. await injectNextI18NextConfigurations(context, props, ['translation']);
  120. return {
  121. props,
  122. };
  123. };
  124. export default LoginPage;